﻿using System;
using System.Collections.Generic;
using Ikadn.Ikon.Types;

namespace Ikadn.Ikon.Factories
{
	/// <summary>
	/// IKADN object factory for IKON arrays.
	/// </summary>
	public class ArrayFactory : IIkadnObjectFactory
	{
		/// <summary>
		/// Sign for IKADN array.
		/// </summary>
		public const char OpeningSign = '[';

		/// <summary>
		/// Closing character for IKON array in textual
		/// representation.
		/// </summary>
		public const char ClosingChar = ']';

		/// <summary>
		/// Sign for IKADN array.
		/// </summary>
		public char Sign
		{
			get { return OpeningSign; }
		}

		/// <summary>
		/// Parses input for a IKADN object.
		/// </summary>
		/// <param name="parser">IKADN parser instance.</param>
		/// <returns>IKADN object generated by factory.</returns>
		public IkadnBaseObject Parse(Ikadn.IkadnParser parser)
		{
			if (parser == null)
				throw new System.ArgumentNullException("parser");

			List<IkadnBaseObject> values = new List<IkadnBaseObject>();

			while (parser.Reader.PeekNextNonwhite() != ClosingChar)
			{
				string startPosition = parser.Reader.PositionDescription;
				if (!parser.HasNext())
					throw new FormatException("Characters from " + startPosition + " to " + parser.Reader.PositionDescription + " couldn't be parsed as IKADN value");

				values.Add(parser.ParseNext());
			}
			parser.Reader.Read();

			return new IkonArray(values);
		}
	}
}
